using System;
using System.Collections.Generic;
using System.Text;
using JobShopModel.Model.FactoryLvl;
using JobShopModel.Model.Station;
using System.Collections;



namespace JobShopModel.Model.FactoryLvl
{
    


    /// <summary>
    /// Class reprensenting the distance between the stations
    /// </summary>
    public class FactoryMap
    {

        public class StationPair
        {
            StationsName start;
            StationsName end;

            public class Comparer : IEqualityComparer<StationPair>
            {

                #region IEqualityComparer<Pair> Membres

                public bool Equals(StationPair x, StationPair y)
                {
                    if (x.start == y.start && x.end == y.end)
                    {
                        return true;
                    }
                    else if (x.start == y.end && x.end == y.start)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }

                public int GetHashCode(StationPair obj)
                {
                    return (int)obj.start ^ (int)obj.end;
                }

                #endregion
            }

            public StationPair(StationsName start, StationsName end)
            {
                this.start = start;
                this.end = end;
            }


        }

        private Dictionary<StationPair, int> stationMap;

        /// <summary>
        /// Default Constructor
        /// Fill all the fields from a text file
        /// </summary>
        public  FactoryMap()
        {
            stationMap = new Dictionary<StationPair, int>(new StationPair.Comparer());
            initMapHardcoded();

        }

        /// <summary>
        /// Create the factory map from a config file.
        /// </summary>
        /// <returns></returns>
        private void initMap()
        {
            //TODO: Extract element from XML File !!
        }

        /// <summary>
        /// Create the map from hardcoded values
        /// To be deleted
        /// </summary>
        private void initMapHardcoded()
        {
            //Only half of the elements are added, it do not matter on the order of the pair,
            //From station 1
            stationMap.Add(new StationPair(StationsName.STATION1, StationsName.STATION2), 90);
            stationMap.Add(new StationPair(StationsName.STATION1, StationsName.STATION3), 100);
            stationMap.Add(new StationPair(StationsName.STATION1, StationsName.STATION4), 200);
            stationMap.Add(new StationPair(StationsName.STATION1, StationsName.STATION5), 180);
            stationMap.Add(new StationPair(StationsName.STATION1, StationsName.IOSTATION), 270);

            //From Station 2
            stationMap.Add(new StationPair(StationsName.STATION2, StationsName.STATION3), 100);
            stationMap.Add(new StationPair(StationsName.STATION2, StationsName.STATION4), 200);
            stationMap.Add(new StationPair(StationsName.STATION2, StationsName.STATION5), 180);
            stationMap.Add(new StationPair(StationsName.STATION2, StationsName.IOSTATION), 270);

            //From station 3
            stationMap.Add(new StationPair(StationsName.STATION3, StationsName.STATION4), 100);
            stationMap.Add(new StationPair(StationsName.STATION3, StationsName.STATION5), 100);
            stationMap.Add(new StationPair(StationsName.STATION3, StationsName.IOSTATION), 180);

            //From Station 4
            stationMap.Add(new StationPair(StationsName.STATION4, StationsName.STATION5), 90);
            stationMap.Add(new StationPair(StationsName.STATION4, StationsName.IOSTATION), 100);

            //From Station 5
            stationMap.Add(new StationPair(StationsName.STATION5, StationsName.IOSTATION), 100);

        }

        /// <summary>
        /// Get the distance between 2 stations
        /// Hide underlying implementation of the map in case of a file based.
        /// If the distance does not exist, an exception is raised ....
        /// </summary>
        /// <param name="start">Starting station</param>
        /// <param name="end">Ending Stations</param>
        /// <returns>Distance between 2 station</returns>
        public int getDistance(StationsName start,StationsName end)
        {
            int distance = -1;
            StationPair key = new StationPair(start,end);

            //Check the input
            if (!stationMap.TryGetValue(key,out distance))
            {
                throw new Exception("Error: Can not find the distance ("+start.ToString()+","+end.ToString()+"), the element may not exist");
            }

            return distance;
        }
    }
}
